package com.medical.literature.document.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.medical.literature.common.exception.BusinessException;
import com.medical.literature.common.vo.Result;
import com.medical.literature.document.dto.RecognitionResult;
import com.medical.literature.document.entity.Literature;
import com.medical.literature.document.entity.LiteratureContent;
import com.medical.literature.document.mapper.LiteratureContentMapper;
import com.medical.literature.document.mapper.LiteratureMapper;
import com.medical.literature.document.service.WebSocketService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.List;

/**
 * 识别结果处理器
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RecognitionResultProcessor {
    
    private final LiteratureMapper literatureMapper;
    private final LiteratureContentMapper literatureContentMapper;
    private final KeywordProcessor keywordProcessor;
    private final WebSocketService webSocketService; // 保留WebSocket服务，但不使用
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * 处理识别结果
     * @param literatureId 文献ID
     * @param recognitionResult 识别结果
     */
    @Transactional
    public void processRecognitionResult(Long literatureId, Result<RecognitionResult> recognitionResult) {
        try {
            log.info("开始处理识别结果，文献ID: {}", literatureId);
            
            // 检查是否成功
            if (recognitionResult == null || !recognitionResult.isSuccess()) {
                log.error("识别服务返回错误: {}", 
                    (recognitionResult != null ? recognitionResult.getMessage() : "未知错误"));
                throw new BusinessException("识别服务返回错误: " + 
                    (recognitionResult != null ? recognitionResult.getMessage() : "未知错误"));
            }
            
            RecognitionResult data = recognitionResult.getData();
            if (data == null) {
                log.error("识别结果数据为空");
                throw new BusinessException("识别结果数据为空");
            }
            
            log.info("识别结果数据: 文献ID={}, 状态={}, 文本长度={}, 关键词数量={}", 
                     data.getLiteratureId(), data.getStatus(), 
                     data.getTextContent() != null ? data.getTextContent().length() : 0,
                     data.getKeywords() != null ? data.getKeywords().size() : 0);
            
            // 记录前几个关键词作为示例
            if (data.getKeywords() != null && !data.getKeywords().isEmpty()) {
                int displayCount = Math.min(5, data.getKeywords().size());
                List<String> sampleKeywords = data.getKeywords().subList(0, displayCount);
                log.info("示例关键词: {}", sampleKeywords);
            }
            
            // 提取文本内容
            String textContent = data.getTextContent() != null ? data.getTextContent() : "";
            
            // 提取关键词
            List<String> keywords = data.getKeywords();
            
            // 保存文献内容
            saveLiteratureContent(literatureId, textContent);
            
            // 处理关键词
            if (keywords != null && !keywords.isEmpty()) {
                keywordProcessor.processLiteratureKeywords(literatureId, keywords);
            }
            
            // 更新文献识别状态为已完成
            updateLiteratureRecognitionStatus(literatureId, 2); // 已识别
            
            // 使用轮询机制替代WebSocket通知
            log.info("文献识别结果处理完成，文献ID: {}", literatureId);
            
        } catch (Exception e) {
            log.error("处理文献识别结果失败，文献ID: {}", literatureId, e);
            // 更新文献识别状态为失败
            updateLiteratureRecognitionStatus(literatureId, 3); // 识别失败
            
            throw new BusinessException("处理识别结果失败: " + e.getMessage());
        }
    }
    
    /**
     * 处理识别结果（JSON字符串版本，用于兼容旧接口）
     * @param literatureId 文献ID
     * @param recognitionResult 识别结果JSON字符串
     */
    @Transactional
    public void processRecognitionResult(Long literatureId, String recognitionResult) {
        try {
            log.info("开始处理识别结果（JSON字符串版本），文献ID: {}", literatureId);
            
            // 解析JSON结果
            com.fasterxml.jackson.databind.JsonNode rootNode = objectMapper.readTree(recognitionResult);
            
            // 检查是否成功
            com.fasterxml.jackson.databind.JsonNode codeNode = rootNode.get("code");
            if (codeNode == null || codeNode.asInt() != 200) {
                log.error("识别服务返回错误: {}", 
                    (rootNode.get("message") != null ? rootNode.get("message").asText() : "未知错误"));
                throw new BusinessException("识别服务返回错误: " + 
                    (rootNode.get("message") != null ? rootNode.get("message").asText() : "未知错误"));
            }
            
            com.fasterxml.jackson.databind.JsonNode dataNode = rootNode.get("data");
            if (dataNode == null || dataNode.isNull()) {
                log.error("识别结果数据为空");
                throw new BusinessException("识别结果数据为空");
            }
            
            // 提取文本内容
            String textContent = dataNode.get("textContent") != null ? 
                dataNode.get("textContent").asText() : "";
            
            // 提取关键词
            List<String> keywords = null;
            com.fasterxml.jackson.databind.JsonNode keywordsNode = dataNode.get("keywords");
            if (keywordsNode != null && keywordsNode.isArray()) {
                keywords = new java.util.ArrayList<>();
                for (com.fasterxml.jackson.databind.JsonNode keywordNode : keywordsNode) {
                    keywords.add(keywordNode.asText());
                }
            }
            
            log.info("识别结果数据: 文献ID={}, 文本长度={}, 关键词数量={}", 
                     literatureId, textContent.length(), keywords != null ? keywords.size() : 0);
            
            // 保存文献内容
            saveLiteratureContent(literatureId, textContent);
            
            // 处理关键词
            if (keywords != null && !keywords.isEmpty()) {
                keywordProcessor.processLiteratureKeywords(literatureId, keywords);
            }
            
            // 更新文献识别状态为已完成
            updateLiteratureRecognitionStatus(literatureId, 2); // 已识别
            
            // 使用轮询机制替代WebSocket通知
            log.info("文献识别结果处理完成，文献ID: {}", literatureId);
            
        } catch (Exception e) {
            log.error("处理文献识别结果失败，文献ID: {}", literatureId, e);
            // 更新文献识别状态为失败
            updateLiteratureRecognitionStatus(literatureId, 3); // 识别失败
            
            throw new BusinessException("处理识别结果失败: " + e.getMessage());
        }
    }
    
    /**
     * 保存文献内容
     * @param literatureId 文献ID
     * @param textContent 文本内容
     */
    private void saveLiteratureContent(Long literatureId, String textContent) {
        log.info("开始保存文献内容，文献ID: {}, 文本长度: {}", literatureId, textContent.length());
        LiteratureContent content = new LiteratureContent();
        content.setLiteratureId(literatureId);
        content.setContentType(1); // 文本内容
        content.setContent(textContent);
        content.setConfidence(new BigDecimal("0.95")); // 置信度
        literatureContentMapper.insert(content);
        log.info("文献内容保存成功，文献ID: {}", literatureId);
    }
    
    /**
     * 更新文献识别状态
     * @param literatureId 文献ID
     * @param status 状态
     */
    private void updateLiteratureRecognitionStatus(Long literatureId, Integer status) {
        log.info("更新文献识别状态，文献ID: {}, 状态: {}", literatureId, status);
        Literature literature = new Literature();
        literature.setId(literatureId);
        literature.setRecognitionStatus(status);
        literatureMapper.updateById(literature);
        log.info("文献识别状态更新成功，文献ID: {}, 状态: {}", literatureId, status);
    }
}